include( 'file_io.lua' )
include( 'messages.lua' )

include( 'animation.lua' )
if CLIENT then

local gi_Padding = 3
local gi_PreviewTile = 44
local gi_OptionButton = 32
local gi_HotboxCatagoryWide = 100
local gi_PropertyPanelWide = 500
local gi_CatagoryDepth = 1
local gi_HotboxHeight = 200

local WHITE = Color(255,255,255,255)
local ORANGE = Color(195,140,45,255)
local DARK_GREY = Color(16,16,16,255)
local GREY = Color(128,128,128,255)

local function CreateLabel(text, color, parent)
	local label = vgui.Create("DLabel", parent) 
	label:SetText(text) 
	label:SetTextColor(color) 
	label:SizeToContents()
	return label
end

local gLastPropertiesPanel = nil
local CreateListPanel = nil
local gCreateCatagoryPanel = nil
local gCreatePropertiesPanel = nil
local gCurrentCatagoryPanel = nil

function HidePropertiesPanel()
	if gLastPropertiesPanel then
		gLastPropertiesPanel:SetVisible(false)
	end
end

function SwitchToPropertiesPanel(panel)
	if panel then
		HidePropertiesPanel()
		gLastPropertiesPanel = panel
		gLastPropertiesPanel:SetVisible(true)
	end
end


/********************************************
 * Creates a pane of image buttons for material
 * selection on entites
 ********************************************/
local function LoadCustomMaterials(dimen, selectedEntity,panel)
	local buttonTable = {}
	local FACE_DIR = "../materials/myproject/materials/"
	local headFn = file.Find(FACE_DIR .. "*.vmt")
	for _, fn in pairs(headFn) do
		local filename = string.sub(fn,1, string.len(fn) - 4)

		local mateiralFilepath = "myproject/materials/" .. filename

		local button = vgui.Create( "DImageButton", panel) 
		button:SetMaterial( mateiralFilepath )
		button:SetSize(40,40)
		button.DoClick = function () 
			print(mateiralFilepath)
			selectedEntity:SetMaterial(mateiralFilepath)
		end
		table.insert(buttonTable,button)
	end

	return buttonTable

end
local function LoadCustomFrames(dimen,panel)

	local buttonTable = {}
	local FACE_DIR = "../materials/myproject/frames/"
	local headFn = file.Find(FACE_DIR .. "*.vmt")
	for _, fn in pairs(headFn) do
		local filename = string.sub(fn,1, string.len(fn) - 4)

		if filename != "widescreen" and filename != "scope" then
			local mateiralFilepath = "myproject/frames/" .. filename

			local button = vgui.Create( "DImageButton", panel) 
			button:SetMaterial( mateiralFilepath ) 
			button:SetSize(dimen,dimen)
			button.DoClick = function () 
				callingEntity.BaseClass.GetRootNode(callingEntity):SetNWString("framing_type", filename)
			end
			table.insert(buttonTable,button)
		end
	end

	return buttonTable

end


function SwitchToCatagory(panel)
	if gCurrentCatagoryPanel != panel then
	
		if gCurrentCatagoryPanel != nil then

			gCurrentCatagoryPanel:SetVisible(false)	
			//When switching through the 'create' list, we want to clear the right most panel
			if gLastPropertiesPanel != nil then 
				gLastPropertiesPanel:SetVisible(false)	
		   end
		
		end

		if panel != nil then
			gCurrentCatagoryPanel = panel
			gCurrentCatagoryPanel:SetVisible(true)
		end
	end
end

function DisplayStillCameraPane(parent, panelName)

end

local PropCollections = {}
local CreateTypes = {}

function DisplayPropPane(parent, collectionName, collectionList)

	//if PropCollections[collectionName] == nil then
	if true == true then
		local paneButtons = {}
		local propPane = vgui.Create( "DPanel", parent) 
		propPane:SetParent(parent)
		propPane:SetSize(parent:GetWide(), parent:GetTall())
		propPane:SetPos(0,0)
		propPane:SetPaintBackground(false)
		propPane:SetVisible(true)
		PropCollections[collectionName] = propPane

		
		local propPaneLable = GetTextLabelEx(collectionName, "Default", propPane)
		propPaneLable:SetPos(gi_Padding * 2, gi_Padding)

		local appearance_label = GetTextLabel("Appearance", propPane)
		appearance_label:SetPos(gi_Padding * 2, propPaneLable:GetTall() + (gi_Padding * 2))
		
		local previewEnt = ents.Create( "prop_physics" )
		if(previewEnt and previewEnt:IsValid()) then
			previewEnt:Spawn()
			previewEnt:SetNoDraw(true)
		end
	
		local misc_label = GetTextLabel("Misc", propPane)
		misc_label:SetPos(propPane:GetWide() - gi_OptionButton - (2 * gi_Padding), propPaneLable:GetTall() + (gi_Padding * 2))
		
		local propPreview = GetImageButton("gui/MMMatPreviewButton", gi_OptionButton, gi_OptionButton, nil,propPane)
		propPreview:SetPos(propPane:GetWide() - gi_OptionButton - (2 * gi_Padding), appearance_label:GetTall() + (3 * gi_Padding) + propPaneLable:GetTall())
		propPreview.DoClick = function()
			propPreview:SetSelected(!propPreview:GetSelected())
			for _, button in pairs(paneButtons) do
				button:EnablePreview(propPreview:GetSelected())
			end
		end

		local propList = vgui.Create("DPanelList", propPane)
		propList:SetPos(gi_Padding, gi_Padding + propPaneLable:GetTall() + (6 * gi_Padding))
		propList:SetSize(propPane:GetWide() - gi_OptionButton - (8 * gi_Padding), propPane:GetTall() - ((9 * gi_Padding) + propPaneLable:GetTall()))
		propList:SetPadding(2)
		propList:SetSpacing(2)
		propList:EnableHorizontal(true)
		propList:EnableVerticalScrollbar(true)

		GetSeperator(propPane:GetWide() - gi_OptionButton - (5 * gi_Padding), 32,0,130,propPane)

		for j, tModelPathname in pairs(collectionList) do
			local button = vgui.Create( "MMPreviewIcon") 
			table.insert(paneButtons, button)
			button:SetModel(tModelPathname)
			button.ModelPathname = tModelPathname
			button:SetSize(gi_PreviewTile,gi_PreviewTile)
			button:SetParent(propPane)
			button:SetPreviewProp(previewEnt)
			button:EnablePreview(false)

			button.DoClick = function() 
				local entPos = LocalPlayer():EyePos() + (LocalPlayer():GetAimVector() * 30)
				local entityData = {};
				entityData.classname = "prop_physics";
				entityData.model = tModelPathname;
				entityData.posX = entPos.x;
				entityData.posY = entPos.y;
				entityData.posZ = entPos.z;
				entityData.physicsInit = SOLID_VPHYSICS;
				entityData.physicsMovetype = MOVETYPE_VPHYSICS;
				datastream.Send("CreateEntity", entityData);
			end
			
			propList:AddItem(button)
		end

	end
	return PropCollections[collectionName]
end

function DisplayActorPane(parent, collectionName, collectionList)

	if PropCollections[collectionName] == nil then

		local paneButtons = {}
		local propPane = vgui.Create( "DPanel", parent) 
		propPane:SetParent(parent)
		propPane:SetSize(parent:GetWide(), parent:GetTall())
		propPane:SetPos(0,0)
		propPane:SetPaintBackground(false)
		propPane:SetVisible(true)
		PropCollections[collectionName] = propPane

		local propPaneLable = GetTextLabelEx(collectionName, "Default", propPane)
		propPaneLable:SetPos(gi_Padding * 2, gi_Padding)

		local previewEnt = ents.Create( "prop_physics" )
		if(previewEnt and previewEnt:IsValid()) then
			previewEnt:Spawn()
			previewEnt:SetNoDraw(true)
		end
	
		local xAn = propPane:GetWide() - gi_OptionButton - (gi_Padding * 2)
		local yAn = gi_Padding + 16
		local misc_label = GetTextLabel("Misc", propPane)
		misc_label:SetPos(xAn,yAn)
		yAn = yAn + misc_label:GetTall() + gi_Padding

		local propPreview = GetImageButton("gui/MMMatPreviewButton", gi_OptionButton, gi_OptionButton, nil,propPane)
		propPreview:SetPos(xAn, yAn)
		propPreview.DoClick = function()
			propPreview:SetSelected(!propPreview:GetSelected())
			for _, button in pairs(paneButtons) do
				button:EnablePreview(propPreview:GetSelected())
			end
		end

		
		xAn = gi_Padding
		yAn = gi_Padding + 16

		local behaviour_label = nil
		local behavePassive = nil
		local behaveSheep = nil
		local behaveViolent = nil
		local behaveStill = nil
		local behaveDead = nil
		local lastClicked = nil
		local npc_class = ""
		local giveEqiupment = GetButtonEx("Give Equipment",nil, 100, 20, propPane)

		behaviour_label = GetTextLabel("Behaviour", propPane)
		behaviour_label:SetPos(xAn + gi_Padding,yAn)
		yAn = yAn + behaviour_label:GetTall() + gi_Padding

		behavePassive = GetButtonEx("Passive",nil,100, 20,  propPane)
		behavePassive.DoClick = function() 
		lastClicked:SetSelected(false) 
		lastClicked = behavePassive
		npc_class = "npc_alyx"
		giveEqiupment:SetDisabled(false)
		behavePassive:SetSelected(true) end
		behavePassive:SetPos(xAn, yAn)
		yAn = yAn + behavePassive:GetTall() + gi_Padding

		behaveStill = GetButtonEx("Still",nil, 100, 20, propPane)
		behaveStill.DoClick = function() 
		npc_class = "npc_breen"
		giveEqiupment:SetDisabled(true)
		lastClicked:SetSelected(false) 
		lastClicked = behaveStill
		behaveStill:SetSelected(true) end
		behaveStill:SetPos(xAn, yAn)
		yAn = yAn + behaveStill:GetTall() + gi_Padding

		behaveDead = GetButtonEx("Dead",nil, 100, 20, propPane)
		behaveDead.DoClick = function() 
		lastClicked:SetSelected(false) 
		giveEqiupment:SetDisabled(true)
		lastClicked = behaveDead
		npc_class = "prop_ragdoll"
		behaveDead:SetSelected(true) end
		behaveDead:SetPos(xAn, yAn)
		yAn = yAn + behaveDead:GetTall() + gi_Padding

		local equipment_label = GetTextLabel("Equipment", propPane)
		equipment_label:SetPos(xAn + gi_Padding,yAn)
		yAn = yAn + equipment_label:GetTall() + gi_Padding

		giveEqiupment.DoClick = function() 
		
		if not giveEqiupment:GetSelected() then
			giveEqiupment:SetSelected(true) 
		else
			giveEqiupment:SetSelected(false) 
		end

		end
		
		giveEqiupment:SetPos(xAn, yAn)
		yAn = yAn + giveEqiupment:GetTall() + gi_Padding

		
		npc_class = "prop_ragdoll"
		giveEqiupment:SetDisabled(true)
		lastClicked = behaveDead
		lastClicked:SetSelected(true)


		local equipment_label_note = GetTextLabel("Note: Only applies\nto passive behaviour", propPane)
		equipment_label_note:SetPos(xAn + gi_Padding,yAn)
		yAn = yAn + equipment_label_note:GetTall() + gi_Padding


		xAn = xAn + 100 + (4 * gi_Padding)

		GetSeperator(xAn, gi_Padding + 16, 0, yAn - (gi_Padding) + 20, propPane)

		xAn = xAn + (4 * gi_Padding)
		yAn = gi_Padding + 16
		

		local appearance_label = GetTextLabel("Appearance", propPane)
		appearance_label:SetPos(xAn,yAn)
		yAn = yAn + appearance_label:GetTall() + gi_Padding

		local propList = vgui.Create("DPanelList", propPane)
		propList:SetPos(xAn - gi_Padding, yAn + gi_Padding)
		propList:SetSize(propPane:GetWide() - xAn - gi_OptionButton - (6 * gi_Padding), propPane:GetTall() - ((10 * gi_Padding) + propPaneLable:GetTall()))
		propList:SetPadding(2)
		propList:SetSpacing(2)
		propList:EnableHorizontal(true)
		propList:EnableVerticalScrollbar(true)

		for j, tModelPathname in pairs(collectionList) do
			local button = vgui.Create( "MMPreviewIcon") 
			table.insert(paneButtons, button)
			button:SetModel(tModelPathname)
			button.ModelPathname = tModelPathname
			button:SetSize(gi_PreviewTile,gi_PreviewTile)
			button:SetParent(propPane)
			button:SetPreviewProp(previewEnt)
			button:EnablePreview(false)

	button.DoClick = function() 
				local entPos = Vector(0,0,0) 
				local trace = LocalPlayer():GetEyeTrace()

				if trace.HitWorld then
					entPos = trace.HitPos + trace.HitNormal
				else
					entPos = LocalPlayer():EyePos() + (LocalPlayer():GetAimVector() * 100)
				end

				local actorData = {};
				actorData.classname = npc_class
				actorData.modelname = tModelPathname
				actorData.posX = entPos.x;
				actorData.posY = entPos.y;
				actorData.posZ = entPos.z;
				actorData.equipment = ""

				if giveEqiupment:GetSelected() == true then 
					if npc_class == "npc_alyx" then
						if tModelPathname == "models/alyx.mdl" then
							actorData.equipment = "weapon_alyxgun"
						else
							actorData.equipment = "weapon_shotgun"
						end
					end
				end

				datastream.Send("CreateActor", actorData);
			end

			propList:AddItem(button)
		end

		yAn = yAn + propList:GetTall() + gi_Padding
		
		xAn = xAn + propList:GetWide() + (2 * gi_Padding)

		GetSeperator(xAn, gi_Padding + 18, 0, yAn - (5 * gi_Padding), propPane)


	end
	return PropCollections[collectionName]
end

function DisplayPropCatagory(parent)

	if CreateTypes["Prop"] == nil then

		local panel = vgui.Create( "DPanel", gCreateCatagoryPanel ) 
		panel:SetPos(0,0)
		panel:SetPaintBackground(false)
		panel:SetSize(parent:GetWide(), parent:GetTall())
		CreateTypes["Prop"] = panel

		//TODO:repeated code
		local currentlySelected = nil
		local updateSelected = function(justClicked)
			if currentlySelected != nil then 
				currentlySelected:SetSelected(false) 
			end
			currentlySelected = justClicked
			currentlySelected:SetSelected(true)
		end

		local catTitle = GetTextLabelEx("Catagory", "Default", panel)
		catTitle:SetPos((parent:GetWide() / 2) - (catTitle:GetWide() / 2),gi_Padding);

		local catList = vgui.Create( "DPanelList", panel) 
		catList:SetPos( 0, gi_Padding + catTitle:GetTall() + gi_Padding ) 
		catList:SetSize( parent:GetWide(), parent:GetTall() - (gi_Padding + catTitle:GetTall() + gi_Padding + gi_Padding + 1))
		catList:SetSpacing(1)
		catList:SetPadding(1)

		local propList = ReadSpawnList("props.txt")
		local propCatagoryCount = 0

		for k, v in pairs(propList) do
			propCatagoryCount = propCatagoryCount + 1
		end

		if propCatagoryCount > 0 then

			local gi_HotboxCatagoryItemTall = (catList:GetTall() / propCatagoryCount)

			for tCatagoryName, tCatagoryList in pairs(propList) do

				local onClickPropType =	function(parent)
					SwitchToPropertiesPanel(DisplayPropPane(gCreatePropertiesPanel, tCatagoryName, tCatagoryList))
					updateSelected(parent)
				end

				catList:AddItem(GetButton(tCatagoryName,onClickPropType, gi_HotboxCatagoryWide,gi_HotboxCatagoryItemTall, catList))
				
			end
		
		end
	end
	
	return CreateTypes["Prop"]
end


/****************************************
 * Displays the camera creation panels in
 * the hotbox
 ****************************************/
function DisplayCameraCatagory(parent)
	if CreateTypes["Camera"] == nil then

		local panel = vgui.Create( "DPanel", gCreateCatagoryPanel ) 
		panel:SetPos(0,0)
		panel:SetPaintBackground(false)
		panel:SetSize(parent:GetWide(), parent:GetTall())
		CreateTypes["Camera"] = panel

		local catTitle = GetTextLabelEx("Type", "Default", panel)
		catTitle:SetPos((parent:GetWide() / 2) - (catTitle:GetWide() / 2),gi_Padding);
	
		//TODO:repeated code
		local currentlySelected = nil
		local updateSelected = function(justClicked)
			if currentlySelected != nil then 
				currentlySelected:SetSelected(false) 
			end
			currentlySelected = justClicked
			currentlySelected:SetSelected(true)
		end

		local catList = vgui.Create( "DPanelList", panel) 
		catList:SetPos( 0, gi_Padding + catTitle:GetTall() + gi_Padding ) 
		catList:SetSize( parent:GetWide(), parent:GetTall() - (gi_Padding + catTitle:GetTall() + gi_Padding + gi_Padding + 1))
		catList:SetSpacing(1)
		catList:SetPadding(1)

		local onClickAnimatedCamera =	function(button)
			SwitchToPropertiesPanel(DisplayAnimatedCameraPane(gCreatePropertiesPanel, "Animated Camera"))
			updateSelected(button)
		end
		local onClickStillCamera =	function(button)
			SwitchToPropertiesPanel(DisplayStillCameraPane(gCreatePropertiesPanel, "Still Camera"))
			updateSelected(button)
		end

		local gi_HotboxCatagoryItemTall = (catList:GetTall() / 2)
		catList:AddItem(GetButton("Animated Camera",onClickAnimatedCamera, gi_HotboxCatagoryWide,gi_HotboxCatagoryItemTall, catList))
		catList:AddItem(GetButton("Still Camera",onClickStillCamera, gi_HotboxCatagoryWide,gi_HotboxCatagoryItemTall, catList))
		
	end
	
	return CreateTypes["Camera"]
end

/****************************************
 * Displays the actor creation panels in
 * the hotbox
 ****************************************/
function DisplayActorCatagory(parent)

	if CreateTypes["Actor"] == nil then

		local panel = vgui.Create( "DPanel", gCreateCatagoryPanel ) 
		panel:SetPos(0,0)
		panel:SetPaintBackground(false)
		panel:SetSize(parent:GetWide(), parent:GetTall())
		CreateTypes["Actor"] = panel

		local catTitle = GetTextLabelEx("Species", "Default", panel)
		catTitle:SetPos((parent:GetWide() / 2) - (catTitle:GetWide() / 2),gi_Padding);
		
		//TODO:repeated code
		local currentlySelected = nil
		local updateSelected = function(justClicked)
			if currentlySelected != nil then 
				currentlySelected:SetSelected(false) 
			end
			currentlySelected = justClicked
			currentlySelected:SetSelected(true)
		end

		local catList = vgui.Create( "DPanelList", panel) 
		catList:SetPos( 0, gi_Padding + catTitle:GetTall() + gi_Padding ) 
		catList:SetSize( parent:GetWide(), parent:GetTall() - (gi_Padding + catTitle:GetTall() + gi_Padding + gi_Padding + 1))
		catList:SetSpacing(1)
		catList:SetPadding(1)

		local actorList = ReadSpawnList("actors.txt")
		local actorCatagoryCount = 0

		for k, v in pairs(actorList) do
			actorCatagoryCount = actorCatagoryCount + 1
		end

		if actorCatagoryCount > 0 then

			local gi_HotboxCatagoryItemTall = (catList:GetTall() / actorCatagoryCount)
			for tCatagoryName, tCatagoryList in pairs(actorList) do

				local onClickPropType =	function(button)
					SwitchToPropertiesPanel(DisplayActorPane(gCreatePropertiesPanel, tCatagoryName, tCatagoryList))
					updateSelected(button)
				end
				catList:AddItem(GetButton(tCatagoryName,onClickPropType, gi_HotboxCatagoryWide,gi_HotboxCatagoryItemTall, catList))
				
			end
		end

		catList:AddItem(GetButton("Actor Roleplay",function(button) SwitchToPropertiesPanel(DisplayRoleplayPane(gCreatePropertiesPanel, "RoleplayPane")) updateSelected(button) end, gi_HotboxCatagoryWide,gi_HotboxCatagoryItemTall, catList))
	end
	
	return CreateTypes["Actor"]
end

local go_LastCreateCatagory = nil

function InitailizeTypeCatagory(parent)
	
	local catTitle = CreateLabel("New", TEXT_LIGHT, parent)
	catTitle:SetPos((gi_HotboxCatagoryWide / 2) - (catTitle:GetWide() / 2),gi_Padding);

	local catList = vgui.Create( "DPanelList", parent ) 
	catList:SetPos( 0, gi_Padding + catTitle:GetTall() + gi_Padding ) 
	catList:SetSize( gi_HotboxCatagoryWide, parent:GetTall() - (gi_Padding + catTitle:GetTall() + gi_Padding + gi_Padding + 1))
	catList:SetSpacing(1)
	catList:SetPadding(1)
		
	local currentlySelected = nil

	local updateSelected = function(justClicked)
		if currentlySelected != nil then 
			currentlySelected:SetSelected(false) 
		end
		currentlySelected = justClicked
		currentlySelected:SetSelected(true)
	end

	local gi_HotboxCatagoryItemTall = catList:GetTall() / 6

	local propButton = GetButton("Prop", nil, parent:GetWide() - 2 * gi_Padding, gi_HotboxCatagoryItemTall, catList)
	propButton.DoClick = function () 
		SwitchToCatagory(DisplayPropCatagory(parent)) 
		updateSelected(propButton)
	end

	local actorButton = GetButton("Actor", nil, parent:GetWide() - 2 * gi_Padding, gi_HotboxCatagoryItemTall, catList)
	actorButton.DoClick = function ()
		SwitchToCatagory(DisplayActorCatagory(parent))
		updateSelected(actorButton)
	end

	local cameraButton = GetButton("Camera", nil, parent:GetWide() - 2 * gi_Padding, gi_HotboxCatagoryItemTall, catList)
	cameraButton.DoClick = function() 
		SwitchToCatagory(DisplayCameraCatagory(parent)) 
		updateSelected(cameraButton)
	end
	local lightingButton = GetButton("Lighting", nil,
					parent:GetWide() - 2 * gi_Padding, gi_HotboxCatagoryItemTall,
					catList)
	lightingButton.DoClick = function() 
		
		updateSelected(lightingButton)
	end

	catList:AddItem(propButton)
	catList:AddItem(actorButton)
	catList:AddItem(cameraButton)
	catList:AddItem(lightingButton)
	catList:AddItem(effectButton)

	return panel
end

function CreatePanel(parent)
	
	local panel = GetPanel(0, gi_HotboxVerticalAnchor, parent:GetWide(), parent:GetTall() - 33, parent)
	if(panel != nil) then
		if CreateListPanel == nil then
			CreateListPanel = GetPanelEx(0,0, gi_HotboxCatagoryWide - gi_Padding, parent:GetTall(), PANEL_LIGHT, panel)
		end
		CreateListPanel:SetParent(panel)
		InitailizeTypeCatagory(CreateListPanel)

		if gCreateCatagoryPanel == nil then
			gCreateCatagoryPanel = GetPanelEx(gi_HotboxCatagoryWide,0, gi_HotboxCatagoryWide - gi_Padding, parent:GetTall(), PANEL_LIGHT, panel)
		end
		gCreateCatagoryPanel:SetParent(panel)

		if gCreatePropertiesPanel == nil then
			gCreatePropertiesPanel = GetPanelEx(2 * gi_HotboxCatagoryWide,0, parent:GetWide() - (2 * gi_HotboxCatagoryWide), parent:GetTall(), PANEL_LIGHT, panel)
		end
		gCreatePropertiesPanel:SetParent(panel)
	end
end	


function PropPanel(parent, selectedEntity)

	local panel = GetPanelEx(0, gi_HotboxVerticalAnchor, parent:GetWide(), parent:GetTall() - 33, PANEL_LIGHT, parent)
	
	/*******************************************
	 * Initalize control panel with data values
	 *******************************************/
	local modelScale = selectedEntity:GetModelScale()
	local modelRotation = selectedEntity:GetAngles()

	/*******************************************
	 * Initalize main controls
	 *******************************************/

	local xAn = 10;
	local xAnNext = 10;
	local yAn = 10;

	/*******************************************
	 * Object scaling control
	 *******************************************/
	local formLabel = GetTextLabel("Object Scale:", panel)
	formLabel:SetPos(xAn,yAn);
	yAn = yAn + formLabel:GetTall() + gi_Padding
	xAnNext = math.Max(xAn, 10 +xAn + formLabel:GetWide())

	local xScale = GetNumberSlider("Horizontal", 0.01, 10, 2, 
	function(parent, value) 
		local origonalScale = selectedEntity:GetModelScale()
		selectedEntity:SetModelScale(Vector(value, origonalScale.y, origonalScale.z))
	end, panel)
	xScale:SetPos( xAn ,yAn) 
	xScale:SetSize( (gi_DirectButtonWidth / 2) - (1.5 * 10), 30 )
	yAn = yAn + xScale:GetTall() + gi_Padding
	xAnNext = math.Max(xAn,10 + xAn + xScale:GetWide())

	local yScale = GetNumberSlider("Vertical", 0.01, 10, 2, 
	function(parent, value) 
		local origonalScale = selectedEntity:GetModelScale()
		selectedEntity:SetModelScale(Vector(origonalScale.x, value, origonalScale.z))
	end, panel)
	yScale:SetPos( xAn ,yAn) 
	yScale:SetSize( (gi_DirectButtonWidth / 2) - (1.5 * 10), 30 )
	yAn = yAn + yScale:GetTall() + gi_Padding
	xAnNext = math.Max(xAn, 10 +xAn + yScale:GetWide())

	local zScale = GetNumberSlider("Depth", 0.01, 10, 2, 
	function(parent, value) 
		local origonalScale = selectedEntity:GetModelScale()
		selectedEntity:SetModelScale(Vector(origonalScale.x, origonalScale.y, value))
	end, panel)
	zScale:SetPos( xAn ,yAn) 
	zScale:SetSize( (gi_DirectButtonWidth / 2) - (1.5 * 10), 30 )
	yAn = yAn + zScale:GetTall() + gi_Padding
	xAnNext = math.Max(xAn,10 + xAn + zScale:GetWide())
	xAn = xAnNext;

	/*******************************************
	 * Object rotation control
	 *******************************************/
	yAn = 10 
	local rotateLabel = GetTextLabel("Object Rotation:", panel)
	rotateLabel:SetPos(xAn,yAn);
	yAn = yAn + rotateLabel:GetTall() + gi_Padding
	xAnNext = math.Max(xAn, 10 +xAn + rotateLabel:GetWide())

	local xRotate = GetNumberSlider("X Axis", 0.0, 360.0, 2, nil, panel)
	xRotate:SetPos( xAn ,yAn) 
	xRotate:SetSize( (gi_DirectButtonWidth / 2) - (1.5 * 10), 30 )
	yAn = yAn + xRotate:GetTall() + gi_Padding
	xAnNext = math.Max(xAn, 10 + xAn + xRotate:GetWide())

	local yRotate = GetNumberSlider("Y Axis", 0.0, 360.0, 2, nil, panel)
	yRotate:SetPos( xAn ,yAn) 
	yRotate:SetSize( (gi_DirectButtonWidth / 2) - (1.5 * 10), 30 )
	yAn = yAn + yRotate:GetTall() + gi_Padding
	xAnNext = math.Max(xAn,10 + xAn + yRotate:GetWide())

	local zRotate = GetNumberSlider("Z Axis", 0.0, 360.0, 2, nil, panel)
	zRotate:SetPos( xAn ,yAn) 
	zRotate:SetSize( (gi_DirectButtonWidth / 2) - (1.5 * 10), 30 )
	yAn = yAn + zRotate:GetTall() + gi_Padding
	xAnNext = math.Max(xAn,10 + xAn + zRotate:GetWide())
	xAn = xAnNext;

	xRotate.OnValueChanged = function(parent, value) 
		print(value)
		selectedEntity:SetAngles(Angle(value, yRotate.Value, zRotate.Value))
	end

	yRotate.OnValueChanged = function(parent, value) 
		print(value)
		selectedEntity:SetAngles(Angle(xRotate.Value,value, zRotate.Value))
	end

	zRotate.OnValueChanged = function(parent, value) 
		print(value)
		selectedEntity:SetAngles(Angle(xRotate.Value, yRotate.Value, value ))
	end

	/*******************************************
	 * Extra controls
	 *******************************************/
	yAn = yAn + gi_Padding
	xAn = gi_Padding

	local controlsLabel = GetTextLabel("Extra controls:", panel)
	controlsLabel:SetPos(xAn + (2 * gi_Padding),yAn);
	yAn = yAn + controlsLabel:GetTall() + gi_Padding
	//xAnNext = math.Max(xAn, 10 + xAn + appearanceLabel:GetWide())

	local freezeOnClick = function (button)
		local entityData = {};
		entityData.entIndex = selectedEntity:EntIndex();
		datastream.Send("ToggleFreeze", entityData);
		button:SetSelected(not button:GetSelected())

		if LocalPlayer():GetNWEntity("CarryEntity") == selectedEntity then
			toggleSelectedEntityPickup()
		end
	end

	local freezeButton = GetButton("Freeze", freezeOnClick, panel)
	freezeButton:SetPos( xAn, yAn )
	freezeButton:SetSize( 80, 20)
	freezeButton:SetSelected(selectedEntity:GetNWBool("IsFreeze"))
	freezeButton.DoClick = freezeOnClick;
	xAn = xAn + freezeButton:GetWide() + gi_Padding

	local deleteOnClick = function ()
		selectedEntity:Remove()
		//panel:Close()
		panel = nil
		local respawnHotbox = {};
		respawnHotbox.traceType = "Default"; 
		ProducerInterface(respawnHotbox)
	end

	local deleteButton = GetButton("Delete", deleteOnClick, panel)
	deleteButton:SetPos( xAn, yAn )	
	deleteButton:SetSize( 80, 20)
	xAn = xAn + deleteButton:GetWide() + gi_Padding

	local copyOnClick = function ()

		local entPos = LocalPlayer():EyePos() + (LocalPlayer():GetAimVector() * 60)
		local entityData = {};
		entityData.classname = "prop_physics";
		entityData.model = selectedEntity:GetModel();
		entityData.posX = entPos.x;
		entityData.posY = entPos.y;
		entityData.posZ = entPos.z;
		entityData.physicsInit = SOLID_VPHYSICS;
		entityData.physicsMovetype = MOVETYPE_VPHYSICS;
		datastream.Send("CreateEntity", entityData);

	end
	local copyButton = GetButton("Copy", copyOnClick, panel)
	copyButton:SetPos( xAn, yAn )	
	copyButton:SetSize( 80, 20)
	xAn = xAn + copyButton:GetWide() + (2 * gi_Padding)

	GetSeperator(xAn, 10 + gi_HotboxVerticalAnchor, 0, panel:GetTall() - (gi_HotboxVerticalAnchor + 10 + 10),panel)

	/*******************************************
	 * Object appearance
	 *******************************************/
	yAn = 10 
	xAn = xAn + gi_Padding * 4
	local appearanceLabel = GetTextLabel("Object Appearance:", panel)
	appearanceLabel:SetPos(xAn + (2 * gi_Padding),yAn);
	yAn = yAn + appearanceLabel:GetTall() + (2 * gi_Padding)
	xAnNext = math.Max(xAn, 10 +xAn + appearanceLabel:GetWide())
				
	local buttonPaneTable = vgui.Create("DPanelList", panel)
	buttonPaneTable:SetPos(xAn, yAn)
	buttonPaneTable:SetSize(panel:GetWide() - (gi_Padding * 5 + xAn), panel:GetTall() - (20 + ( 4 * gi_Padding ) + 10 + appearanceLabel:GetTall()))
	buttonPaneTable:SetPadding(2)
	buttonPaneTable:SetSpacing(2)
	buttonPaneTable:EnableHorizontal(true)
	buttonPaneTable:EnableVerticalScrollbar(true)

	for _, button in pairs( LoadCustomMaterials(gi_ConstructButtonWidth - (2 * gi_Padding),selectedEntity,buttonPaneTable) ) do

		buttonPaneTable:AddItem(button)

	end

	yAn = yAn + buttonPaneTable:GetTall() + gi_Padding

	local makeInvisibleFunction = function (button)

		if selectedEntity.Invisible then
			button:SetText("Make Invisible")
			selectedEntity.Invisible = !selectedEntity.Invisible
			selectedEntity:SetNoDraw(selectedEntity.Invisible)
		else
			button:SetText("Make Visible")
			selectedEntity.Invisible = true
			selectedEntity:SetNoDraw(true)
		end
	end

	local makeInvisibleButton = GetButton("Make Invisible", makeInvisibleFunction, panel)
	makeInvisibleButton:SetPos( xAn, yAn)
	makeInvisibleButton:SetSize( 100, 20)

	if selectedEntity.Invisible then
		makeInvisibleButton:SetSelected(true)
	end

	xAn = xAn + makeInvisibleButton:GetWide() + gi_Padding


	local resetMaterialFunction = function ()
		selectedEntity:SetMaterial("")
	end
	local resetMaterialButton = GetButton("Reset Material", resetMaterialFunction, panel)
	resetMaterialButton:SetPos( xAn, yAn)
	resetMaterialButton:SetSize( 100, 20)		

end


function AnimatedCameraPanel(parent, cameraEntity)

	local panel = GetPanel(0, gi_HotboxVerticalAnchor, parent:GetWide(), parent:GetTall() - 33, parent)
	

	local selectedCameraParameters = cameraEntity:GetParameters()
	local coloumnWidth = parent:GetWide() / 4

	/*******************************************
	 * Component declarations
	 *******************************************/
	local leftNav				= nil
	local rightNav				= nil
	local cameraZoomSlider		= nil
	local camera_shake			= nil
	local selectRangeButton		= nil
	local shakeAgressionSlider	= nil
	local shakeFrequencySlider	= nil
	local interNodeDurSlider	= nil
	local stopNodeDurSlider		= nil
	local positionTrackCheck	= nil
	local directionTrackCheck	= nil
	local triggerLinkCheck		= nil
	local deleteTriggerList		= nil
	local createActorTrigger	= nil

	/*******************************************
	 * Reinitalization functionality
	 *******************************************/
	local initializePanelComponents = function(cameraNode)
		cameraEntity = cameraNode
		local cameraParameters = cameraNode:GetParameters()
		selectedCameraParameters = cameraParameters
		local prevNode = cameraNode.BaseClass.GetPrevNode(cameraNode)
		local nextNode = cameraNode.BaseClass.GetNextNode(cameraNode)
		if prevNode and prevNode:IsValid() then 
			leftNav:SetDisabled(false)
		else 
			leftNav:SetDisabled(true) 
		end
		
		if nextNode and nextNode:IsValid() then
			rightNav:SetDisabled(false)
		else
			rightNav:SetDisabled(true)
		end

		print("initalizing camera panel")
		print("For camera: " ,cameraNode)
		for Key, SequenceName in pairs(cameraNode:GetActorSequenceNames()) do
			deleteTriggerList:AddItem(GetButton(string.format("Remove %s", SequenceName), 
			function(button) 
			cameraEntity:RemoveActorSequence(SequenceName) 
			deleteTriggerList:RemoveItem(button)
			end, deleteTriggerList))
			print("button ", SequenceName, " added")
		end

		for _, toolSearch in pairs(LocalPlayer():GetWeapons()) do
			if toolSearch:GetClass() == "interaction" then
				if toolSearch:GetState() == STATE_GATHER_CAMERA_SEQUENCES then
					createActorTrigger:SetSelected(true)
				else
					createActorTrigger:SetSelected(false)
				end	
				break
			end
		end


		positionTrackCheck:SetSelected(cameraParameters.IsShowTrack)
		directionTrackCheck:SetSelected(cameraParameters.IsShowDirection)
		triggerLinkCheck:SetSelected(cameraParameters.IsShowTangents)
		
		cameraZoomSlider:SetValue(cameraParameters.Zoom)
		shakeAgressionSlider:SetValue(cameraParameters.ShakeAgression)
		shakeFrequencySlider:SetValue(cameraParameters.ShakeFrequency)
		interNodeDurSlider:SetValue(cameraParameters.TimeTransition)
		stopNodeDurSlider:SetValue(cameraParameters.TimeStop)

	end

	local xAn = gi_Padding;
	local yAn = gi_Padding - 2;

	local firstPanel = GetPanelEx(6,36, (parent:GetWide() / 4) - (2 * gi_Padding ),
	parent:GetTall() - 40, PANEL_LIGHT, parent) 

	/*firstPanel:SetParent(parent)
	firstPanel:SetSize((parent:GetWide() / 4) - (2 * gi_Padding ), parent:GetTall() - 40)
	firstPanel:SetPos(6,36)
	firstPanel:SetPaintBackground(true)
	firstPanel:SetVisible(true)
	*/
	local cameraSelectionLable = GetTextLabelEx("Camera Configuration", "Default", firstPanel)
	cameraSelectionLable:SetPos(xAn, yAn)

	yAn = yAn + cameraSelectionLable:GetTall() + gi_Padding + gi_Padding + gi_Padding 

	/*******************************************
	 * Track control
	 *******************************************/
	local trackNav = GetTextLabel("Track Navigation:", firstPanel)
	trackNav:SetPos(xAn,yAn);
	yAn = yAn + trackNav:GetTall() + gi_Padding
	
	
	leftNav = GetSystemButton("left", (firstPanel:GetWide() - (xAn * 2) - gi_Padding) / 2,20, nil, firstPanel)
	leftNav:SetPos( xAn + gi_Padding ,yAn) 
	leftNav.DoClick = function ()
		local prevNode = cameraEntity.BaseClass.GetPrevNode(cameraEntity)
		if prevNode and prevNode:IsValid() then

			
			local currentCameraParams = cameraEntity:GetParameters()

			//Tells the current camera it is no longer selected, updates 'range selection'
			local cameraParamData = { };
			cameraParamData.entIndexA		= cameraEntity:EntIndex()
			cameraParamData.parametersA		= currentCameraParams
			cameraParamData.ShowFromCameraID = cameraEntity:GetNWInt(ID_NODE_ID)
			
			//Tells the prev camera that it is selected
			local prevCameraParameters		= prevNode:GetParameters()
			prevCameraParameters.ShowFromCameraID = cameraEntity:EntIndex()
			cameraParamData.entIndexB		= prevNode:EntIndex()
			cameraParamData.parametersB		= prevCameraParameters
			cameraParamData.ShowFromCameraID = prevNode:EntIndex()
			
			datastream.Send("SetDualCameraParameters", cameraParamData);
			initializePanelComponents(prevNode)

			//Tells the player to look at the newly selected node
			local lookVector = prevNode:GetPos() - LocalPlayer():EyePos()
			lookVector:Normalize()
			LocalPlayer():SetEyeAngles(lookVector:Angle())
		end
	end

	rightNav = GetSystemButton("right", (firstPanel:GetWide() - (xAn * 2) - gi_Padding) / 2,20, nil, firstPanel)
	rightNav:SetPos( xAn + (firstPanel:GetWide() - (xAn * 2) - gi_Padding) / 2 ,yAn) 
	rightNav.DoClick = function ()

		local nextNode = cameraEntity.BaseClass.GetNextNode(cameraEntity)
		if nextNode and nextNode:IsValid() then

			//Tells the current camera it is no longer selected, updates 'range selection'
			selectedCameraParameters.ShowFromCameraID = cameraEntity:EntIndex()
			local currentCameraParams = cameraEntity:GetParameters()

			local cameraParamData = { };
			cameraParamData.entIndexA		= cameraEntity:EntIndex()
			cameraParamData.parametersA		= currentCameraParams
						
			//Tells the prev camera that it is selected
			local nextCameraParameters		= nextNode:GetParameters()
			nextCameraParameters.ShowFromCameraID = cameraEntity:EntIndex()
			cameraParamData.entIndexB		= nextNode:EntIndex()
			cameraParamData.parametersB		= nextCameraParameters
			cameraParamData.ShowFromCameraID = nextNode:EntIndex()

			datastream.Send("SetDualCameraParameters", cameraParamData);
			initializePanelComponents(nextNode)
			
			//Tells the player to look at the newly selected node
			local lookVector = nextNode:GetPos() - LocalPlayer():EyePos()
			lookVector:Normalize()
			LocalPlayer():SetEyeAngles(lookVector:Angle())
		end
	end

	yAn = yAn + rightNav:GetTall() + gi_Padding

	/*******************************************
	 * Preview playback
	 *******************************************/
	local trackPreview = GetTextLabel("Preview Playback:", firstPanel)
	trackPreview:SetPos(xAn,yAn);
	yAn = yAn + trackPreview:GetTall() + gi_Padding
	
	local playButton = GetImageButton("gui/MMMatPlayButton", 30, 30, nil, firstPanel)
	playButton:SetPos( xAn + gi_Padding ,yAn) 
	playButton.DoClick = function()

		local anchorCamera = cameraEntity
		gAllowScreenEffects = false

		//play
		local anchorParameters = anchorCamera:GetParameters()
		anchorParameters.ShowPreview = 1
		anchorParameters.PreviewState = 1

		local anchorParamData = { };
		anchorParamData.entIndex		= anchorCamera:EntIndex()
		anchorParamData.parameters		= anchorParameters
		datastream.Send("SetCameraParameters", anchorParamData);
			gAllowScreenEffects = false
			local params = cameraEntity:GetParameters()
			params.ShowPreview = 1
			params.PreviewState = 1
			params.ShowFromCameraID = GetRootNode(cameraEntity):EntIndex()
			datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters	= params });
		end
	
	local pauseButton = GetImageButton("gui/MMMatPauseButton", 30, 30, nil, firstPanel)
	pauseButton:SetPos( xAn + (2 * gi_Padding) + playButton:GetWide(),yAn) 
	pauseButton.DoClick = function()
		gAllowScreenEffects = false
		local params = cameraEntity:GetParameters()
		print(cameraEntity)
		params.ShowPreview = 1
		params.PreviewState = 2
		//params.ShowFromCameraID = GetRootNode(cameraEntity):EntIndex()
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters	= params });
	end

	local stopButton = GetImageButton("gui/MMMatStopButton", 30, 30, nil, firstPanel)
	stopButton:SetPos( xAn + (3 * gi_Padding) + playButton:GetWide() + pauseButton:GetWide() ,yAn) 
	stopButton.DoClick = function()
		gAllowScreenEffects = true
		local params = cameraEntity:GetParameters()
		params.ShowPreview = 0
		params.PreviewState = 0
		params.ShowFromCameraID = GetRootNode(cameraEntity):EntIndex()
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters	= params });
	end

	local jumpButton = GetImageButton("gui/MMMatJumpButton", 30, 30, nil, firstPanel)
	jumpButton:SetPos( xAn + (4 * gi_Padding) + playButton:GetWide() + pauseButton:GetWide() + stopButton:GetWide(),yAn) 
	jumpButton.DoClick = function()

		gAllowScreenEffects = false
		local params = cameraEntity:GetParameters()
		params.ShowPreview = 1
		params.PreviewState = 3
		params.ShowFromCameraID = cameraEntity:EntIndex()
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters	= params });
	end


	yAn = yAn + jumpButton:GetTall() + gi_Padding

	/*******************************************
	 * Display controls
	 *******************************************/

	local trackDisplay = GetTextLabel("Display:", firstPanel)
	trackDisplay:SetPos(xAn,yAn);
	yAn = yAn + trackDisplay:GetTall() + gi_Padding

	
	positionTrackCheck = GetButton("Track",nil,firstPanel)
	positionTrackCheck:SetPos( xAn, yAn) 
	positionTrackCheck:SetSize( (gi_DirectButtonWidth / 4) - (gi_Padding * 2), 20)
	positionTrackCheck.DoClick = function()
		local settingConfig = not positionTrackCheck:GetSelected()
		selectedCameraParameters.IsShowTrack = settingConfig
		if settingConfig == true then
			selectedCameraParameters.IsShowTrack = 1
		else
			selectedCameraParameters.IsShowTrack = 0
		end
		positionTrackCheck:SetSelected(settingConfig)
	
		local cameraParamData = { };
		cameraParamData.entIndex		= cameraEntity:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters

		datastream.Send("SetCameraParameters", cameraParamData);

		positionTrackCheck:SetSelected(settingConfig)
	end
	
	directionTrackCheck = GetButton("Directions" ,nil, firstPanel) 
directionTrackCheck:SetPos( xAn + positionTrackCheck:GetWide() + gi_Padding, yAn) 
	directionTrackCheck:SetSize( (gi_DirectButtonWidth / 4) - (gi_Padding * 2), 20)
	directionTrackCheck.DoClick = function()
		
		local settingConfig = not directionTrackCheck:GetSelected()
		if settingConfig == true then
			selectedCameraParameters.IsShowDirection = 1
		else
			selectedCameraParameters.IsShowDirection = 0
		end
		directionTrackCheck:SetSelected(settingConfig)
		
		local cameraParamData = { };
		cameraParamData.entIndex		= cameraEntity:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters

		datastream.Send("SetCameraParameters", cameraParamData);
		directionTrackCheck:SetSelected(settingConfig)
	end

	triggerLinkCheck = GetButton("Tangents" ,nil, firstPanel) 
	triggerLinkCheck:SetPos( xAn + directionTrackCheck:GetWide() + gi_Padding + positionTrackCheck:GetWide() + gi_Padding, yAn) 
	triggerLinkCheck:SetSize( (gi_DirectButtonWidth / 4) - (gi_Padding * 2), 20)
	triggerLinkCheck.DoClick = function()
		local settingConfig = not triggerLinkCheck:GetSelected()
		if settingConfig == true then
			selectedCameraParameters.IsShowTangents = 1
		else
			selectedCameraParameters.IsShowTangents = 0
		end
		triggerLinkCheck:SetSelected(settingConfig)
		
		local cameraParamData = { };
		cameraParamData.entIndex		= cameraEntity:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters

		datastream.Send("SetCameraParameters", cameraParamData);
	end
	
	/*******************************************
	 * Phenomena
	 *******************************************/
	local secondPanel = GetPanelEx(coloumnWidth + (2 * gi_Padding ),36, (parent:GetWide() / 4) - (2 * gi_Padding ),
	parent:GetTall() - 40, PANEL_LIGHT, parent) 

	yAn =cameraSelectionLable:GetTall() + gi_Padding + gi_Padding + gi_Padding // cameraSelectionLable:GetTall() + gi_Padding + gi_Padding 
	xAn = gi_Padding * 2//coloumnWidth + (4 * gi_Padding )

	local cameraPhen = GetTextLabel("Camera Phenomina:", secondPanel)
	cameraPhen:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + cameraPhen:GetTall()

	cameraZoomSlider = GetNumberSlider("Lense Zoom", 0, 100, 1, 
	function(cmp,val) 
		local params = cameraEntity:GetParameters()
		params.Zoom = val
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters = params});
	end, secondPanel)
	cameraZoomSlider:SetPos( xAn,yAn) 
cameraZoomSlider:SetSize( secondPanel:GetWide() - (gi_Padding * 4), 33 )
	yAn = yAn + gi_Padding + cameraZoomSlider:GetTall()

	local camera_shake = GetTextLabel("Camera Shake:", secondPanel)
	camera_shake:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + camera_shake:GetTall()
	
	local earthquake = GetImageButton( "gui/earth_shake", 48, 32, nil, secondPanel)
	earthquake:SetPos(xAn+ gi_Padding,  yAn)

	local walkshake = GetImageButton( "gui/walk_shake", 48, 32, nil, secondPanel)
	walkshake:SetPos(xAn+ gi_Padding+  gi_Padding + walkshake:GetWide(), yAn)

	local waveyshake = GetImageButton( "gui/wavey_shake", 48, 32, nil, secondPanel)
	waveyshake:SetPos(xAn+ gi_Padding+  gi_Padding+ walkshake:GetWide() + gi_Padding + waveyshake:GetWide(), yAn)

	yAn= yAn + (2 * gi_Padding) + waveyshake:GetTall()

	shakeAgressionSlider = GetNumberSlider("Aggression", 0, 170, 1, 
		function(cmp,val) 
		local params = cameraEntity:GetParameters()
		params.ShakeAgression = val
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters = params});
		end, secondPanel)
	shakeAgressionSlider:SetPos( xAn,yAn) 
shakeAgressionSlider:SetSize( (secondPanel:GetWide() - (7 * gi_Padding)) / 2 , 33 )

	shakeFrequencySlider = GetNumberSlider("Frequency", 0, 25, 1, 
		function(cmp,val) 
		local params = cameraEntity:GetParameters()
		params.ShakeFrequency = val
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters = params});
		end, secondPanel)
	shakeFrequencySlider:SetPos( xAn + shakeAgressionSlider:GetWide() + gi_Padding,yAn) 
	shakeFrequencySlider:SetSize( (secondPanel:GetWide()- gi_Padding - gi_Padding) / 2 , 33 )
	yAn = yAn + gi_Padding + shakeFrequencySlider:GetTall()

	/*******************************************
	 * Time control
	 *******************************************/
	local thirdPanel = GetPanelEx((coloumnWidth * 2) + (2* gi_Padding ),36, (parent:GetWide() / 4) - (2 * gi_Padding ),
	parent:GetTall() - 40, PANEL_LIGHT, parent) 

	yAn = cameraSelectionLable:GetTall() + gi_Padding + gi_Padding + gi_Padding
	xAn = gi_Padding * 2 //(coloumnWidth + gi_Padding) * 2

	local timeControl = GetTextLabel("Time Control:", thirdPanel)
	timeControl:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + timeControl:GetTall()

	interNodeDurSlider = GetNumberSlider("Transition Duration", 0, 600, 1, 
		function(cmp,val) 
		local params = cameraEntity:GetParameters()
		params.TimeTransition = val
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters = params});
		end, thirdPanel)
	interNodeDurSlider:SetPos( xAn ,yAn) 
interNodeDurSlider:SetSize( thirdPanel:GetWide() - (gi_Padding * 4), 33 )
	yAn = yAn + gi_Padding + interNodeDurSlider:GetTall()

	stopNodeDurSlider = GetNumberSlider("Stop Duration", 0, 600, 1, 
		function(cmp,val)
		local params = cameraEntity:GetParameters()
		params.TimeStop = val
		datastream.Send("SetCameraParameters", {entIndex = cameraEntity:EntIndex(), parameters = params});
		end, thirdPanel)
	stopNodeDurSlider:SetPos( xAn ,yAn) 
stopNodeDurSlider:SetSize( thirdPanel:GetWide() - (gi_Padding * 4), 33 )
	//stopNodeDurSlider:SetConVar(gv_CameraNodeDur:GetName())
	yAn = yAn + gi_Padding + stopNodeDurSlider:GetTall()
	
	
	///***************************************
	// * Define framing options for track 
	// * creation
	// ***************************************/
	local industry_templates =  GetTextLabel("Industry Standard Framing:", thirdPanel)
	industry_templates:SetPos(xAn, yAn)
	yAn = yAn + industry_templates:GetTall() + gi_Padding
	
	local normalFrameButton = vgui.Create("DImageButton", thirdPanel) 
	normalFrameButton:SetMaterial("gui/frame_tv")
	normalFrameButton:SetSize(gi_PreviewTile,gi_PreviewTile)
	normalFrameButton:SetPos(xAn,yAn)
	normalFrameButton.DoClick = function () 
	selectedCameraParameters.FrameType = 0;
	local cameraParamData = { };
		cameraParamData.entIndex		= cameraEntity:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters
		datastream.Send("SetCameraParameters", cameraParamData);
	end

	local widescreenFrameButton = vgui.Create("DImageButton", thirdPanel) 
	widescreenFrameButton:SetMaterial("gui/frame_widescreen")
	widescreenFrameButton:SetSize(gi_PreviewTile,gi_PreviewTile)
	widescreenFrameButton:SetPos(xAn + gi_PreviewTile + gi_Padding + gi_Padding,yAn)
	widescreenFrameButton.DoClick = function () 
	selectedCameraParameters.FrameType = 1;
	local cameraParamData = { };
		cameraParamData.entIndex		= cameraEntity:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters
		datastream.Send("SetCameraParameters", cameraParamData);
	end

	local scopeFrameButton = vgui.Create("DImageButton", thirdPanel) 
	scopeFrameButton:SetMaterial("gui/frame_scope")
	scopeFrameButton:SetSize(gi_PreviewTile,gi_PreviewTile)
	scopeFrameButton:SetPos(xAn + gi_PreviewTile + gi_Padding + gi_Padding + gi_PreviewTile + gi_Padding + gi_Padding,yAn)
	scopeFrameButton.DoClick = function () 
	selectedCameraParameters.FrameType = 2;
	local cameraParamData = { };
		cameraParamData.entIndex		= cameraEntity:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters
		datastream.Send("SetCameraParameters", cameraParamData);
	end
	yAn = yAn + scopeFrameButton:GetTall() + gi_Padding

	/*******************************************
	 * Trigger Event Creation
	 *******************************************/
	local fourthPanel = GetPanelEx((coloumnWidth * 3) + (2* gi_Padding ),36, (parent:GetWide() / 4) - (2 * gi_Padding ),
	parent:GetTall() - 40, PANEL_LIGHT, parent) 

	yAn=cameraSelectionLable:GetTall() + gi_Padding + gi_Padding + gi_Padding  //cameraSelectionLable:GetTall() + gi_Padding + gi_Padding 
	xAn = (2*gi_Padding) //coloumnWidth * 3

	local triggerEvents = GetTextLabel("Create Trigger Event:", fourthPanel)
	triggerEvents:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + triggerEvents:GetTall()

	local onTriggerWithRoleplay = function(button) 

		local tool = nil
		for _, toolSearch in pairs(LocalPlayer():GetWeapons()) do
			if toolSearch:GetClass() == "interaction" then
				tool = toolSearch
				break
			end
		end
		if not tool then
			return
		end

		if tool:GetState() == STATE_GATHER_CAMERA_SEQUENCES then
			datastream.Send("SetToolState", {stateID = STATE_INTERACT})
			createActorTrigger:SetSelected(false)
		else
			datastream.Send("SetSequenceAssignCamera", { CameraEntIndex = cameraEntity:EntIndex()})
			createActorTrigger:SetSelected(true)
			CloseHotbox()
		end	

	end

	createActorTrigger = GetButton("With roleplay", onTriggerWithRoleplay, fourthPanel)
	createActorTrigger:SetPos( xAn ,yAn) 
	createActorTrigger:SetSize( ((gi_DirectButtonWidth / 6) * 2) + gi_Padding , 23 )

	createLightTrigger = GetButton("With light", nil, fourthPanel)
	createLightTrigger:SetDisabled(true)
	createLightTrigger:SetPos( createActorTrigger:GetWide() + xAn + (2 * gi_Padding),yAn) 
	createLightTrigger:SetSize( ((gi_DirectButtonWidth / 6) * 2) , 23 )
	yAn = yAn + gi_Padding + createLightTrigger:GetTall()

	local deleteTriggerEvents = GetTextLabel("Remove Trigger Event:", fourthPanel)
	deleteTriggerEvents:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + deleteTriggerEvents:GetTall()

	deleteTriggerList = vgui.Create("DPanelList", fourthPanel)
	deleteTriggerList:SetPos(xAn, yAn)
	deleteTriggerList:SetSize(fourthPanel:GetWide() - (4 * gi_Padding), fourthPanel:GetTall() - 90)
	deleteTriggerList:SetPadding(2)
	deleteTriggerList:SetSpacing(2)
	deleteTriggerList:EnableHorizontal(false)
	deleteTriggerList:EnableVerticalScrollbar(true)

	//Once all the components are created, initalize them
	initializePanelComponents(cameraEntity)

end

/*********************************************************************************************************************************
 * ACTOR SEQUENCE PANEL
 * Definition for the user interface panel that contains controls for configuring nodes on an actor sequence
 * TODO: in desperate need of a tidy up
 *********************************************************************************************************************************/
function ActorSequencePanel(parent, sequenceNode)

	local panel = GetPanel(0, gi_HotboxVerticalAnchor, parent:GetWide(), parent:GetTall() - 33, parent)

	local nodeParameters = sequenceNode:GetParameters()
	local coloumnWidth = parent:GetWide() / 4

	/*******************************************
	 * Component declarations
	 *******************************************/
	local leftNav				= nil
	local rightNav				= nil
	local positionTrackCheck	= nil
	local assocActorsList		= nil
	local assignActorsButton	= nil
	local animSequenceList		= nil
	local animTransition		= nil
	local addAnimationSequence	= nil
	//local speedSlider			= nil

	local tool = nil
	local toolState	= nil
	for _, toolSearch in pairs(LocalPlayer():GetWeapons()) do
		if toolSearch:GetClass() == "interaction" then
			toolState = toolSearch:GetState()
			tool = toolSearch
			break
		end
	end
	if not toolState then
		return
	end

	local updateSequenceNode = function(node, parameters)

		if not (node and node:IsValid()) then
			return
		end

		parameters.AnimationQue = {}
		for _, item in pairs(animSequenceList:GetItems()) do
			table.insert(parameters.AnimationQue, {Animation = item.CurrentAnimation, Effect = item.CurrentEffect, Target = item.CurrentTarget})
		end
		parameters.TransitionAnimation = animTransition.CurrentValue
		node:SetParameters(parameters)
		
		print("\n********** PARAMETERS **********")
		print("Actors:")
		for _,o in pairs(parameters.OwnedActors) do
			print(o)
		end
		print("Animation Sequence:")
		print("Anim: \t\tEffect:\t\tTarget:")
		for _,o in pairs(parameters.AnimationQue) do
			print(o.Animation, "", o.Effect, "", o.Target)
		end
		print("Transition Animation:")
		print(parameters.TransitionAnimation)
		print("*********************************\n")


	end

	/*******************************************
	 * Reinitalization functionality
	 *******************************************/
	local initializePanelComponents = function(node, parameters)
		local prevNode = node.BaseClass.GetPrevNode(node)
		local nextNode = node.BaseClass.GetNextNode(node)
		leftNav:SetDisabled(not (prevNode and prevNode:IsValid()))
		rightNav:SetDisabled(not (nextNode and nextNode:IsValid()))
				 
		if toolState == STATE_GATHER_SEQUENCE_ACTORS then
			assignActorsButton:SetText("Stop Assigning Actors")
			assignActorsButton:SetSelected(true)
		else
			assignActorsButton:SetText("Assign Actors")
			assignActorsButton:SetSelected(false)
		end
	
		//Initalize the associated actors of this node
		assocActorsList:Clear()
		for _, actorData in pairs(parameters.OwnedActors) do

			local removeActorButton = GetButtonEx("Remove " .. actorData:GetModel(), nil, assocActorsList:GetWide(), 15, assocActorsList); 
			removeActorButton.DoClick = function()
			
				local newActors = {}
				for ak, ao in pairs(parameters.OwnedActors) do
				if ao != actorData then	print(actorData:GetModel()) table.insert(newActors, ao) end
				end
				parameters.OwnedActors = newActors
				updateSequenceNode(node, parameters)
				assocActorsList:RemoveItem(removeActorButton)
				assocActorsList:InvalidateLayout()
			end
			assocActorsList:AddItem(removeActorButton)
		end
		
		//Initalize the animation sequence of this node
		animSequenceList:Clear()
		for _, animationEventData in pairs(parameters.AnimationQue) do

			local sequenceEvent = GetAnimationSequenceItem(animSequenceList)

			sequenceEvent.OnDataChanged = function() 
				updateSequenceNode(node,parameters)
			end

			sequenceEvent.AnimationButton:SetText(animationEventData.Animation)
			sequenceEvent.EffectButton:SetText(animationEventData.Effect)
			sequenceEvent.TargetButton:SetText(animationEventData.Target)
			sequenceEvent.CurrentAnimation	= animationEventData.Animation
			sequenceEvent.CurrentEffect		= animationEventData.Effect
			sequenceEvent.CurrentTarget		= animationEventData.Target

			animSequenceList:AddItem(sequenceEvent)
		end

		//Initalize the transition animation,etc of this node
		if nodeParameters.TransitionAnimation then
			animTransition.CurrentValue = parameters.TransitionAnimation
			animTransition.MenuButton:SetText(parameters.TransitionAnimation)
		end

		//When the add animation button is clicked, update the current node
		addAnimationSequence.DoClick = function ()
			local item = GetAnimationSequenceItem(animSequenceList)
			item.OnDataChanged = function() updateSequenceNode(node, parameters) end
			animSequenceList:AddItem(item)

			table.insert(parameters.AnimationQue, {Animation = item.CurrentAnimation, Effect = item.CurrentEffect, Target = item.CurrentTarget})
			updateSequenceNode(node, parameters)
		end

		//allows sequence nav to work
		sequenceNode = node
	end

	local xAn = gi_Padding;
	local yAn = gi_Padding - 2;

	local firstPanel = GetPanelEx(6,36, (parent:GetWide() / 4) - (2 * gi_Padding ),
	parent:GetTall() - 40, PANEL_LIGHT, parent) 

	local cameraSelectionLable = GetTextLabelEx("Sequence Configuration", "Default", firstPanel)
	cameraSelectionLable:SetPos(xAn, yAn)

	yAn = yAn + cameraSelectionLable:GetTall() + gi_Padding + gi_Padding + gi_Padding 

	/*******************************************
	 * Track control
	 *******************************************/
	local trackNav = GetTextLabel("Sequence Navigation:", firstPanel)
	trackNav:SetPos(xAn,yAn);
	yAn = yAn + trackNav:GetTall() + gi_Padding
	

	leftNav = GetSystemButton("left", (firstPanel:GetWide() - (xAn * 2) - gi_Padding) / 2,20, nil, firstPanel)
	leftNav:SetPos( xAn + gi_Padding ,yAn) 


	rightNav = GetSystemButton("right", (firstPanel:GetWide() - (xAn * 2) - gi_Padding) / 2, 20, nil, firstPanel)
	rightNav:SetPos( ((firstPanel:GetWide() - (xAn * 2) - gi_Padding) / 2) + gi_Padding,yAn) 
	
	leftNav.DoClick = function ()
		local prevNode = sequenceNode.BaseClass.GetPrevNode(sequenceNode)
		if prevNode and prevNode:IsValid() then

			initializePanelComponents(prevNode, prevNode:GetParameters())

			//Tells the player to look at the newly selected node
			local lookVector = prevNode:GetPos() - LocalPlayer():EyePos()
			lookVector:Normalize()
			LocalPlayer():SetEyeAngles(lookVector:Angle())
		end
	end
	rightNav.DoClick = function ()

		local nextNode = sequenceNode.BaseClass.GetNextNode(sequenceNode)
		if nextNode and nextNode:IsValid() then
			
			initializePanelComponents(nextNode, nextNode:GetParameters())
			
			//Tells the player to look at the newly selected node
			local lookVector = nextNode:GetPos() - LocalPlayer():EyePos()
			lookVector:Normalize()
			LocalPlayer():SetEyeAngles(lookVector:Angle())
		end
	end

	yAn = yAn + rightNav:GetTall() + gi_Padding

	/*******************************************
	 * Preview playback
	 *******************************************/
	local trackPreview = GetTextLabel("Preview Actor Sequence:", firstPanel)
	trackPreview:SetPos(xAn,yAn);
	yAn = yAn + trackPreview:GetTall() + gi_Padding
	
	local playButton = GetImageButton("gui/MMMatPlayButton", 30, 30, nil, firstPanel)
	playButton:SetPos( xAn + gi_Padding ,yAn) 
	playButton.DoClick = function()
		nodeParameters.PlayState = 1
		sequenceNode:SetParameters(nodeParameters)
	end
	
	local stopButton = GetImageButton("gui/MMMatStopButton", 30, 30, nil, firstPanel)
	stopButton:SetPos( xAn + (gi_Padding) + playButton:GetWide(),yAn) 
	stopButton.DoClick = function()
		nodeParameters.PlayState = 0
		sequenceNode:SetParameters(nodeParameters)
	end

	yAn = yAn + stopButton:GetTall() + gi_Padding

	/*******************************************
	 * Display controls
	 *******************************************/

	local trackDisplay = GetTextLabel("Display:", firstPanel)
	trackDisplay:SetPos(xAn,yAn);
	yAn = yAn + trackDisplay:GetTall() + gi_Padding

	
	positionTrackCheck = GetButton("Track",nil,firstPanel)
	positionTrackCheck:SetPos( xAn, yAn) 
	positionTrackCheck:SetDisabled(true)
	positionTrackCheck:SetSize( (gi_DirectButtonWidth / 4) - (gi_Padding * 2), 20)
	positionTrackCheck.DoClick = function()
		local settingConfig = not positionTrackCheck:GetSelected()
		selectedCameraParameters.IsShowTrack = settingConfig
		positionTrackCheck:SetSelected(settingConfig)
	
		local cameraParamData = { };
		cameraParamData.entIndex		= sequenceNode:EntIndex()
		cameraParamData.parameters		= selectedCameraParameters

		datastream.Send("SetCameraParameters", cameraParamData);

	end
	
	/*******************************************
	 * Actor association
	 *******************************************/
	local secondPanel = GetPanelEx(coloumnWidth + (2 * gi_Padding ),36, (parent:GetWide() / 4) - (2 * gi_Padding ), parent:GetTall() - 40, PANEL_LIGHT, parent) 

	yAn = gi_Padding - 2  + gi_Padding + gi_Padding + trackNav:GetTall() + gi_Padding;
	xAn = gi_Padding * 2

	local associated_actors = GetTextLabel("Actor Association:", secondPanel)
	associated_actors:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + associated_actors:GetTall()

	assocActorsList = vgui.Create("DPanelList", secondPanel)
	assignActorsButton = GetButton("Assign Actors",nil, secondPanel)
	assignActorsButton.DoClick = function()

		toolState = tool:GetState()

		if toolState == STATE_GATHER_SEQUENCE_ACTORS then
			local toolStateData = {};
			toolStateData.stateID = STATE_INTERACT				 
			datastream.Send("SetToolState", toolStateData)

			assignActorsButton:SetText("Assign Actors")
			assignActorsButton:SetSelected(false)
		else
			//Note: this sets the tool to STATE_GATHER_SEQUENCE_ACTORS automaiically
			datastream.Send("SetActorAssignWaypoint", { WaypointEntIndex = sequenceNode:EntIndex()})
			CloseHotbox()
		end	
	end

	assignActorsButton:SetPos(xAn,yAn)
	assignActorsButton:SetSize(160,20)
	yAn = yAn + assignActorsButton:GetTall() + (2 * gi_Padding)

	local actor_associated =  GetTextLabel("Assigned Actors:", secondPanel)
	actor_associated:SetPos(xAn, yAn)
	yAn = yAn + actor_associated:GetTall() + (2*gi_Padding)

	assocActorsList:SetPos(xAn, yAn)
	assocActorsList:SetSize(secondPanel:GetWide() - (4 * gi_Padding), parent:GetTall() - yAn - (16 * gi_Padding))
	assocActorsList:SetPadding(2)
	assocActorsList:SetSpacing(2)
	assocActorsList:EnableHorizontal(false)
	assocActorsList:EnableVerticalScrollbar(true)

	/*******************************************
	 * Animation sequence control
	 *******************************************/
	
	local thirdPanel = GetPanelEx((coloumnWidth * 2) + (2* gi_Padding ),36, (parent:GetWide() / 2) - (4 * gi_Padding ),
	parent:GetTall() - 40, PANEL_LIGHT, parent) 

	local transitionsList = {}
	for tranName, tranCode in pairs(transitions) do
		
		if tranCode == "" then
			table.insert(transitionsList, {Label = tranName})
		else
			table.insert(transitionsList,{Label = tranName, Func = function() animTransition.CurrentValue = tranName updateSequenceNode(sequenceNode, nodeParameters) end})
		end
	end

	animTransition = GetDropMenu(transitionsList, thirdPanel);
	yAn = cameraSelectionLable:GetTall() + gi_Padding + gi_Padding + gi_Padding
	xAn = gi_Padding * 2 //(coloumnWidth + gi_Padding) * 2

	local animationSequence = GetTextLabel("Sequence:", thirdPanel)
	animationSequence:SetPos(xAn,yAn);
	yAn = yAn + gi_Padding + animationSequence:GetTall()

	local animCatTitle = GetTextLabel("Animation", thirdPanel)
	animCatTitle:SetPos(xAn + (gi_Padding * 2),yAn);
	local soundCatTitle = GetTextLabel("Effect", thirdPanel)
	soundCatTitle:SetPos(xAn + (thirdPanel:GetWide() * 0.23) + (gi_Padding),yAn);
	local soundCatTitle = GetTextLabel("Target", thirdPanel)
	soundCatTitle:SetPos(xAn + (thirdPanel:GetWide() * 0.46),yAn);

	GetSeperator(thirdPanel:GetWide() - (thirdPanel:GetWide() * 0.2), yAn,0,120,thirdPanel)

	yAn = yAn + gi_Padding + animCatTitle:GetTall()
	animSequenceList = vgui.Create("DPanelList", thirdPanel)
	animSequenceList:SetPos(xAn, yAn)
	animSequenceList:SetSize(thirdPanel:GetWide() - (4 * gi_Padding) - (thirdPanel:GetWide() * 0.2), thirdPanel:GetTall() - animationSequence:GetTall() - (gi_Padding * 6)  )
	animSequenceList:SetPadding(2)
	animSequenceList:SetSpacing(2)
	animSequenceList:EnableHorizontal(false)
	animSequenceList:EnableVerticalScrollbar(true)

	//When the animation sequence list has been interacted with, update the current node
	animSequenceList.OnDataChanged = function()

		nodeParameters.AnimationQue = {}
		for _, item in pairs(animSequenceList:GetItems()) do
			table.insert(nodeParameters.AnimationQue, {Animation = item.CurrentAnimation, Effect = item.CurrentEffect, Target = item.CurrentTarget})
		end
		updateSequenceNode(sequenceNode, nodeParameters)
	end

	yAn = cameraSelectionLable:GetTall() + (5 * gi_Padding)

  	local animationLabel = GetTextLabel("Animation:", thirdPanel)
	animationLabel:SetPos(thirdPanel:GetWide() - (thirdPanel:GetWide() * 0.2) + (gi_Padding * 2),yAn);
	yAn = yAn + gi_Padding + animationLabel:GetTall()

	addAnimationSequence = GetButtonEx("Add", addAnimation, thirdPanel:GetWide() * .2 - (gi_Padding * 4), 20, thirdPanel)
	addAnimationSequence:SetPos(thirdPanel:GetWide() + (2 * gi_Padding) - (thirdPanel:GetWide() * 0.2),yAn );
	yAn = yAn + (addAnimationSequence:GetTall() + (gi_Padding * 2))

  	local transitionAnim = GetTextLabel("Transition:", thirdPanel)
	transitionAnim:SetPos(thirdPanel:GetWide() - (thirdPanel:GetWide() * 0.2) + (gi_Padding * 2),yAn);
	yAn = yAn + gi_Padding + transitionAnim:GetTall()
	
	animTransition:SetSize(thirdPanel:GetWide() * .2 - (gi_Padding * 4), 20)		
	animTransition:SetPos(thirdPanel:GetWide() + (2 * gi_Padding) - (thirdPanel:GetWide() * 0.2),yAn );
	yAn = yAn + gi_Padding + animTransition:GetTall()

  	/*local speedLabel = GetTextLabel("Speed:", thirdPanel)
	speedLabel:SetPos(thirdPanel:GetWide() - (thirdPanel:GetWide() * 0.2) + (gi_Padding * 2),yAn);
	yAn = yAn + gi_Padding + speedLabel:GetTall()
	
	speedSlider:SetSize(thirdPanel:GetWide() * .2 - (gi_Padding * 4), 30)		
	speedSlider:SetPos(thirdPanel:GetWide() + (2 * gi_Padding) - (thirdPanel:GetWide() * 0.2),yAn );
	yAn = yAn + gi_Padding + speedSlider:GetTall()*/

	//Once all the components are created, initalize them
	initializePanelComponents(sequenceNode, nodeParameters)

end

end //CLIENT